#pragma once
#include <nlohmann/json.hpp>
#include <string>
#include <filesystem>
#include <vector>
#include "simpleLoger.hpp"

#define DISABLE_DIRECT_OUTPUT "关闭默认输出，使用日志管理器"

#ifndef DISABLE_DIRECT_OUTPUT
#include <chrono>
#include <iomanip>
#include <sstream>
#define GET_LOCAL_TIME                                                                                      \
    []() {                                                                                                  \
        auto now = std::chrono::system_clock::now();                                                        \
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;     \
        std::time_t t = std::chrono::system_clock::to_time_t(now);                                          \
        std::tm tm = *std::localtime(&t);                                                                   \
        std::ostringstream oss;                                                                             \
        oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S.") << std::setw(3) << std::setfill('0') << ms.count(); \
        return oss.str();                                                                                   \
    }()
#define FILE_LINE   " - " << __FILE__ << "[" << __LINE__ << "]- "
#define OUTPUT_ERRR std::cerr << GET_LOCAL_TIME << FILE_LINE
#define OUPUT_INFO  std::cout << GET_LOCAL_TIME << FILE_LINE
#endif

struct ConfigStruct {
public:
    struct IO_controller_config {
    public:
        enum IO { Y1 = 0, Y2 = 1, Y3 = 2, Y4 = 3 };
        bool m_isopen = true;
        std::string Yx[4] = {"default", "default", "default", "default"};
        bool m_Yx_isOpen[4] = {false, false, false, false};
    } m_IO_controller_config;
    struct temperature_config {
    public:
        enum CONTROL_MODE {
            AUTO_CONTROL = 0,
            KEEP_COLSE = 1,
            KEEP_OPEN = 2
        };  // 控制模式：自动模式，保持关闭，保持打开
        bool m_isopen = true;
        IO_controller_config::IO m_bind_controller_func_index = IO_controller_config::Y1;
        bool m_open_to_output_state = true;
        float m_temperature_Threshold_open = 40.0;
        float m_temperature_Threshold_close = 30.0;
        CONTROL_MODE m_control_mode = temperature_config::AUTO_CONTROL;
        std::string m_description = "";
    } m_temperature_config;
    struct weight_config {
    public:
        enum CONTROL_MODE { ADD_WITH_PIC = 0 };
        bool m_isopen = true;
        bool m_record_real_weight_data = true;
        uint32_t m_freq_ms_record = 500;
        bool m_auto_take_pic = true;
        CONTROL_MODE m_control_mode = weight_config::ADD_WITH_PIC;
        float m_min_add_step_weight = 50.0;
        float m_permitted_data_fluctuations = 10.0;
        int m_over_permit_wait_period = 50;
        std::string m_description = "";
    } m_weight_config;
    void read_config(const nlohmann::json& __config);
};

class ConfigManager {
public:
    explicit ConfigManager(const std::string& configFileName);

    // 加载配置文件
    void loadConfig();

    // 保存配置文件
    void saveConfig() const;

    // 安全获取配置项（支持多层路径）
    template <typename T>
    static T getSafe(
        const std::string& path,
        const T& defaultValue = T(),
        const nlohmann::json& configJson = m_configJson) {
        try {
            const nlohmann::json* current = &configJson;
            for (const auto& key : splitPath(path)) {
                if (key.front() == '[' && key.back() == ']') {
                    // 处理数组访问
                    if (!current->is_array())
                        return defaultValue;

                    // 解析索引
                    std::string indexStr = key.substr(1, key.length() - 2);  // 去掉 []
                    size_t index = std::stoi(indexStr);
                    if (index >= current->size())
                        return defaultValue;

                    current = &(*current)[index];
                } else {
                    // 普通对象访问
                    if (!current->contains(key))
                        return defaultValue;
                    current = &current->at(key);
                }
            }
            return current->get<T>();
        } catch (...) {
            return defaultValue;
        }
    }

    // 获取完整配置
    const nlohmann::ordered_json& getConfig() const;

protected:
    static nlohmann::ordered_json m_configJson;  // 当前配置文件内容

private:
    std::filesystem::path configPath;

    // 验证配置文件内容
    bool validateConfig() const;

    // 重置为默认配置
    void resetToDefault();

    // 解析路径
    static std::vector<std::string> splitPath(const std::string& path);
};